package Demo4;


import java.util.PriorityQueue;

class TimerTask implements Comparable<TimerTask>{
   private Runnable task;
    private long time;

    public TimerTask(Runnable task, long time) {
        this.task = task;
        this.time = time;
    }

    public void run(){
        task.run();
    }
    public long getTime() {
        return time;
    }

    @Override
    public int compareTo(TimerTask o) {
        return (int)(this.time-o.time);
    }
}


class Timer{
    private PriorityQueue<TimerTask>queue=new PriorityQueue<>();
    Object lock=new Object();

    public void schedule(Runnable task,long delay){
        synchronized (lock){
            TimerTask timerTask=new TimerTask(task, System.currentTimeMillis()+delay);
            queue.offer(timerTask);
            lock.notify();
        }
    }

    public Timer() {
    Thread t=new Thread(()->{
        while(true){
                try {
                    synchronized (lock){
                        while(queue.isEmpty()){
                            lock.wait();
                        }

                    TimerTask task=queue.peek();
                    if(System.currentTimeMillis()<task.getTime()){
                        lock.wait(task.getTime()-System.currentTimeMillis());
                    }else {
task.run();
queue.poll();
                    }
                }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
        }
    });
       t.start();
    }

}


public class Main10 {
    public static void main(String[] args) {
        Timer timer=new Timer();
        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 3000");
            }
        },3000);
        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2000");
            }
        },2000);

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1000");
            }
        },1000);

    }
}
